package org.uim.cricket.afetcher.exec.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;

import org.uim.cricket.afetcher.AFlogger;
import org.uim.cricket.afetcher.FetcherProperties;
import org.uim.cricket.afetcher.args.ArgumentGeneratable;
import org.uim.cricket.afetcher.exec.AnalyzerExecutable;

public class DefaultAnalyzerExecutor implements AnalyzerExecutable {

	private ArgumentGeneratable argGenerator = null;
	private String repoPath = null;
	
	private FetcherProperties prop = null;
	private String analyzerJarFile = null;
	private File analFile = null;
	
	private int totalAnalyzed = 0;
	private int successAnalyzed = 0;
	
	@Override
	public void runAnalyzer(FetcherProperties prop) throws Exception {
		this.prop = prop;
		
		if (this.argGenerator == null) {
			throw new IllegalArgumentException("ArgumentGeneratable interface can't be empty!");
		}
		if (repoPath == null) {
			throw new IllegalArgumentException("Match repository path can't be empty!");
		}
		
		File folder = new File(this.repoPath);
		if (!folder.exists()) {
			AFlogger.error(" Defined match repository folder doesn't exist!");
			AFlogger.error("    [" + folder.getAbsolutePath() + "]");
			throw new FileNotFoundException("Defined match repository folder doesn't exist! [" + folder.getAbsolutePath() + "]");
		}
		/*if (!folder.isDirectory()) {
			AFlogger.error(" Defined match repository folder is not a Directory!");
			AFlogger.error("     Found another entity representing as a repository directory");
			AFlogger.error("    [" + folder.getAbsolutePath() + "]");
			throw new FileNotFoundException("Defined match repository folder is not a Directory! [" + folder.getAbsolutePath() + "]");
		}
		*/
		
		analyzerJarFile = buildAnalyzerPath(prop);
		AFlogger.debug(" Analyzer bat file: [" + analyzerJarFile + "]"); 
		if (!new File(analyzerJarFile).exists()) {
			AFlogger.error(" Can't find analyzer jar file!");
			throw new FileNotFoundException("Analyzer jar file not found! [" + analyzerJarFile + "]");
		}
		
		analFile = new File(this.analyzerJarFile);
		
		this.scanFolder(folder);
		
		AFlogger.debug(" Completed executing all files!");
		
	}

	private void scanFolder(File entity) throws Exception {
		
		if (entity.isFile()) {
			AFlogger.debug("  executing analyzer...");
			
			if (prop.getProp().containsKey("parser.src.file")) {
				prop.getProp().setProperty("parser.src.file", entity.getAbsolutePath());
			} else {
				prop.getProp().put("parser.src.file", entity.getAbsolutePath());
			}
			
			String args = this.argGenerator.generateArguments(prop);
			
			ArrayList<String> argList = new ArrayList<String>();
			argList.add("java");
			argList.add("-jar");
			argList.add(this.analFile.getName());
			String tmp = "";
			boolean inq = false;
			for (int i=0;i<args.length();i++) {
				if (args.charAt(i) == '\"') {
					inq = !inq;
					continue;
				}
				if (inq) {
					tmp += args.charAt(i)+ "";
					continue;
				}
				if (!inq && args.charAt(i) == ' ') {
					argList.add(tmp);
					tmp = "";
					continue;
				} else {
					tmp += (args.charAt(i) + "");
				}
			}
			argList.add(tmp);
			args = "java -jar " + this.analFile.getName() + " " + args ;
			
			AFlogger.debug(" setting working dir as: " + this.analFile.getParent());
			AFlogger.debug(" executing > " + args);
			AFlogger.debug("   no of param: " + argList.size());
			RuntimeExecutor jarexec = new RuntimeExecutor();
			boolean res = jarexec.execute(argList, this.analFile.getParent(), null);
			
			totalAnalyzed++;
			if (res) successAnalyzed++;
			
		} else {
			
			File[] files = entity.listFiles();
			for (File f : files) {
				this.scanFolder(f);
			}
			
		}
		
	}
	
	public void setArgGenerator(ArgumentGeneratable argGenerator) {
		this.argGenerator = argGenerator;
	}
	
	public ArgumentGeneratable getArgGenerator() {
		return argGenerator;
	}

	@Override
	public void setRepositoryPath(String theRepoPath) {
		this.repoPath = theRepoPath;
	}
	
	private String buildAnalyzerPath(FetcherProperties prop) {
		String file = prop.getProperty("analyzer.jar.file");
		if (file == null) return null;
		
		return file;
	}

	@Override
	public int getTotalAnalyzedFiles() {
		return this.totalAnalyzed;
	}

	@Override
	public int getSuccessAnalyzedFiles() {
		return this.successAnalyzed;
	}
	
}
